package top.gbyun.engine.actor;

import akka.actor.OneForOneStrategy;
import akka.actor.SupervisorStrategy;
import akka.japi.pf.DeciderBuilder;
import lombok.extern.slf4j.Slf4j;
import top.gbyun.core.ActorSystemContext;
import top.gbyun.core.msg.ComponentLifecycleMsg;
import top.gbyun.engine.processor.ComponentMsgProcessor;

import java.time.Duration;

/**
 *
 * @author gengbin
 * @date 2024-12-25-14:41
 */
@Slf4j
public abstract class ComponentActor<P extends ComponentMsgProcessor> extends  ContextAwareActor {
    protected final String flowId;
    protected P processor;

    public ComponentActor(String flowId,ActorSystemContext systemContext) {
        super(systemContext);
        this.flowId=flowId;

    }

    protected void setProcessor(P processor) {
        this.processor = processor;
    }

    @Override
    public void preStart() {
        try {
            //RuleActorMessageProcessor
            log.info("[{}][{}]流程处理器启动.", processor.getClass().getName(),flowId);
            processor.start(getContext());
        } catch (Exception e) {
            log.warn("[{}][{}]流程处理器启动失败，失败原因:{} ",  processor.getClass().getName(),flowId,e);
        }
    }

    @Override
    public void postStop() {
        try {
            log.info("[{}][{}]流程处理器销毁.", processor.getClass().getName(),flowId);
            if (processor != null) {
                processor.stop(getContext());
            }
        } catch (Exception e) {
            log.warn("[{}][{}] Failed to stop {} processor", processor.getClass().getName(),flowId,e);
        }
    }


    protected void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
        log.debug("[{}][{}] onComponentLifecycleMsg: [{}]", flowId, msg.getType(), msg.getEvent());
        try {
            switch (msg.getEvent()) {
                case CREATED:
                    processor.onCreated(getContext());
                    break;
                case UPDATED:
                    processor.onUpdate(getContext());
                    break;
                case ACTIVATED:
                    processor.onActivate(getContext());
                    break;
                case SUSPENDED:
                    processor.onSuspend(getContext());
                    break;
                case DELETED:
                    processor.onStop(getContext());
                    break;
                default:
                    break;
            }
//            logLifecycleEvent(msg.getEvent());
        } catch (Exception e) {
            log.error("消息处理失败");
            //logAndPersist("onLifecycleMsg", e, true);
//            logLifecycleEvent(msg.getEvent(), e);
        }
    }

    /**
     * 容错策略
     * @author gengbin
     * @date 2024/12/19 15:20
     * @param null
     * @return
     */
    private static SupervisorStrategy strategy = new OneForOneStrategy(
            5,
            Duration.ofMinutes(1),
            DeciderBuilder
                    .match(NullPointerException.class, e -> SupervisorStrategy.resume())
                    .match(Exception.class, e -> SupervisorStrategy.restart())
                    .matchAny(o -> SupervisorStrategy.escalate())
                    .build()
    );

    @Override
    public SupervisorStrategy supervisorStrategy() {
        return strategy;
    }
}
